package com.dnjn.happiness.system.sensitive;

import com.dnjn.happiness.common.core.utils.StringUtils;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;

import java.io.IOException;
import java.util.Objects;

@NoArgsConstructor
@AllArgsConstructor
public class SensitiveSerializer extends JsonSerializer<String> implements ContextualSerializer {

    // 脱敏类型
    private SensitiveType sensitiveType;
    // 前几位不脱敏
    private Integer prefixNoMaskLen;
    // 最后几位不脱敏
    private Integer suffixNoMaskLen;
    // 用什么打码
    private String symbol;

    @Override
    public void serialize(String origin, final JsonGenerator jsonGenerator,
                          final SerializerProvider serializerProvider) throws IOException {
        if (StringUtils.isEmpty(origin)) {
            origin = null;
        }
       /** todo 本人信息 及有敏感信息权限人员不用脱敏； x
        使用权限接口 /system/user/getSensitiveInfo/{userId} 查询敏感信息
        */

        if (null != sensitiveType) {
            switch (sensitiveType) {
                case CUSTOMER:
                    jsonGenerator.writeString(SensitiveUtil.desValue(origin, prefixNoMaskLen, suffixNoMaskLen, symbol));
                    break;
                case CHINESE_NAME:
                    jsonGenerator.writeString(SensitiveUtil.hideChineseName(origin));
                    break;
                case ID_CARD_NUM:
                    jsonGenerator.writeString(SensitiveUtil.hideIDCard(origin));
                    break;
                case MOBILE_PHONE:
                    jsonGenerator.writeString(SensitiveUtil.hidePhone(origin));
                    break;
                case FIXED_PHONE:
                    jsonGenerator.writeString(SensitiveUtil.hideFixedPhone(origin));
                    break;
                case EMAIL:
                    jsonGenerator.writeString(SensitiveUtil.hideEmail(origin));
                    break;
                case PASSWORD:
                    jsonGenerator.writeString(SensitiveUtil.hidePassword(origin));
                    break;
                case BANKCARD:
                    jsonGenerator.writeString(SensitiveUtil.hideBankCard(origin));
                    break;
                case ADDRESS:
                    jsonGenerator.writeString(SensitiveUtil.hideAddress(origin));
                    break;
                default:
                    throw new IllegalArgumentException("unknown privacy type enum " + sensitiveType);
            }
        }
    }

    @Override
    public JsonSerializer<?> createContextual(final SerializerProvider serializerProvider,
                                              final BeanProperty beanProperty) throws JsonMappingException {
        if (null != beanProperty) {
            if (Objects.equals(beanProperty.getType().getRawClass(), String.class)) {
                SensitiveEncrypt privacyEncrypt = beanProperty.getAnnotation(SensitiveEncrypt.class);
                if (null == privacyEncrypt) {
                    privacyEncrypt = beanProperty.getContextAnnotation(SensitiveEncrypt.class);
                }
                if (null != privacyEncrypt) {
                    return new SensitiveSerializer(privacyEncrypt.type(), privacyEncrypt.prefixNoMaskLen(),
                            privacyEncrypt.suffixNoMaskLen(), privacyEncrypt.symbol());
                }
            }
            return serializerProvider.findValueSerializer(beanProperty.getType(), beanProperty);
        }
        return serializerProvider.findNullValueSerializer(null);
    }

}